package BitManipulation;

public class _393_UTF_8Validation {
    public boolean validUtf8_1(int[] data) {
        // the position of bytes in UTF-8
        int pos = 1;
        int length = 0;
        for (int bt : data) {
           //initial new byte
            int firstByte = (bt & 255);
            if (length == 0) {
                //represent 0xxxxxxxx
                if ((firstByte & 128) == 0) {
                    //represent 110xxxxxxxx
                } else if ((firstByte & 224) == 192) {
                    length = 2;
                } else if ((firstByte & 240) == 224) {
                    length = 3;
                } else if ((firstByte & 248) == 240) {
                    length = 4;
                } else {
                    return false;
                }
            } else if (length == 2) {
                if ((firstByte & 192) != 128) {
                    return false;
                } else {
                    length = 0;
                }
                //3 bytes
            } else if (length == 3) {
                if (pos == 1) {
                    if ((firstByte & 192) != 128) {
                        return false;
                    } else {
                        pos++;
                    }
                } else {
                    if ((firstByte & 192) != 128) {
                        return false;
                    } else {
                        length = 0;
                        pos = 1;
                    }
                }
            } else {
                if (pos < 3) {
                    if ((firstByte & 192) != 128) {
                        return false;
                    } else {
                        pos++;
                    }
                } else {
                    if ((firstByte & 192) != 128) {
                        return false;
                    } else {
                        length = 0;
                        pos = 1;
                    }
                }
            }
        }

        return length == 0;
    }

    //more elegant solution
    public boolean validUtf8(int[] data) {
        int cnt = 0;
        for(int d : data){
            if(cnt == 0){
                if((d>>5) == 0b110) cnt = 1;
                else if((d>>4) == 0b1110) cnt=2;
                else if((d>>3) == 0b11110) cnt=3;
                else if((d>>7) != 0) return false;
            }else{
                if((d>>6) != 0b10) return false;
                cnt--;
            }
        }
        return cnt == 0;
    }
}
